約 6,125,502 件
https://w.atwiki.jp/youdead/pages/6.html
エラー番号から「ありがちなミス」を発見しよう 目次 目次 fatal error C1010 error LNK2005 とか LNK1169 とか error LNK2005などCPPUnit導入失敗時 error LNK2019通常時 テンプレート定義時に発生した時 コメント fatal error C1010 原因) プロジェクトがプリコンパイル済みヘッダファイルを使用する設定の場合、すべてのcppファイルにおいてstdafx.h をインクルードしておく必要があります。 対応) おとなしくすべてのcppファイルにおいてstdafx.h をインクルードする。 プロジェクトがプリコンパイル済みヘッダファイルを使用しない設定に変更してしまう。(非推奨) error LNK2005 とか LNK1169 とか error LNK2005など CPPUnit導入失敗時 現象) 「"bool __cdecl std uncaught_exception(void)" (?uncaught_exception@std@@YA_NXZ) は既に libcpmtd.lib(uncaught.obj) で定義されています。 」とか表示される。 対応) ランタイムライブラリがマルチスレッド デバッグ DLLになっていない可能性があります。マルチスレッド デバッグではなくマルチスレッド デバッグ DLLであることに注意してください。 error LNK2019 通常時 原因) 定義のない、宣言されただけの関数を呼び出している。 対応) 定義を書く テンプレート定義時に発生した時 現象) テンプレートを ヘッダーAに宣言 ソースファイルAに定義 ソースファイルBからヘッダーAを参照し、テンプレートを使おうとする この時エラーが発生する。 原因) このエラーは宣言だけ合って定義のない関数を呼び出したりすると出てきたりするんですが、実は似たようなことが起こっている。 テンプレートはコンパイル時に型が決定し、そのときに型に合った中身(定義)を作ります。 ビルドによる実行ファイルの生成は コンパイラで各ソースファイルを1つずつコンパイルしてオブジェクトファイル(ソースファイルを機械語に変換したもの)を生成。 リンカでオブジェクトファイル間の関数呼び出しを対応させ、EXEファイルを生成します。 コンパイルは各ソースファイル1つ1つが独立して行われる。 以上のことから次のようになっていると考えられる。 (例)ソースファイルBにchar型を指定してテンプレート関数を使用した場合 char型のテンプレート関数の定義は生成されません。 次のような事態になっているはずです。 ソースファイルBにはテンプレート<char>関数の呼び出し文が書かれているだけ。 ソースファイルBはヘッダーAを参照しているもテンプレートの宣言が書かれているだけ。 コンパイラはテンプレート<char>関数がどこか別のソースファイルに定義されていると考える。 結果⇒リンク段階でテンプレート<char>関数なんて存在しないことがわかり、リンカエラーになったと判断される。 対応) テンプレート定義をソースファイルにではなく、テンプレートを宣言したヘッダーファイルに書き込めばよいものと思われる。 コメント 名前 コメント
https://w.atwiki.jp/objcmemo/pages/79.html
// 選択したファイル名を取得する + (NSString*)getImageFileName (UIImagePickerController*)picker pickingMediaInfo (NSDictionary *)info { __block NSString* ret = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^{ if (picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary) { NSURL *imageURL = [info valueForKey UIImagePickerControllerReferenceURL]; ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset) { ALAssetRepresentation *representation = [myasset defaultRepresentation]; ret = [representation filename]; dispatch_semaphore_signal(semaphore); }; ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init]; [assetslibrary assetForURL imageURL resultBlock resultblock failureBlock nil]; } }); dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); return ret; } /* * 写真アルバムアクセス状況を取得する */ // AssetsLibrary.frameworkを組み込む NSString *message = nil; if (![UIImagePickerController isSourceTypeAvailable UIImagePickerControllerSourceTypeCamera]) { message = @"カメラを利用できません。"; } ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus]; switch (status) { case ALAuthorizationStatusNotDetermined message = @"まだ許可ダイアログ出たことない"; break; case ALAuthorizationStatusRestricted message = @"機能制限(ペアレンタルコントロール)で許可されてない"; break; case ALAuthorizationStatusDenied message = @"許可ダイアログで\"いいえ\"が押されています\n" "設定アプリ - プライバシー 写真 - 該当アプリを\"オン\"する必要があります"; break; case ALAuthorizationStatusAuthorized message = @"写真へのアクセスが許可されています"; break; default break; } if (message.length) { [[[UIAlertView alloc] initWithTitle @"確認" message message delegate nil cancelButtonTitle @"OK" otherButtonTitles nil] show]; }
https://w.atwiki.jp/bokuyo/pages/178.html
zlib 1.2.6 をVisual C++でビルドする zlib 1.2.6(January 29, 2012) をWindows 環境に導入します。あれやこれやしていた zlib 1.2.6 を導入したときのメモ を踏まえて、今回は手短に手順を示していきたいところです。 Visual C++ 2010 Express を使用しています。32bit(x86) 環境です。適宜、お使いの環境に合わせて読み解いてください Visual Studio 2012 で zlib 1.2.7 をビルドしたときのメモは次になりますzlib 1.2.7 を Visual Studio 2012 RC でビルドする zlib 1.2.7 を Visual Studio 2012 Express でビルドする ダウンロード http //zlib.net/(公式サイト)から「zlib source code, version 1.2.6, zipfile format」をダウンロードします。 ダウンロードした"zlib126.zip" ファイルを解凍します。以降の説明では、面倒なので解凍先をデスクトップ(Desktop)にしています inffas32.obj と match686.obj をビルドする コマンドプロンプトを開き、以下を順に実行。vcvars32.bat で環境変数を読み込んで、bld_ml32.bat でinffas32.obj と match686.obj をビルドしてます "C \Program Files\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat" cd Desktop/zlib-1.2.6/contrib/masmx86 bld_ml32.bat ビルドする zlib-1.2.6/contrib/vstudio/vc10/zlibvc.sln をVisual C++ 2010 で開きます zlibvc プロジェクトのプロパティを開き、[構成プロパティ]- [全般]ターゲット名を"$(ProjectName)" から "zlibwapi" に変更してください。 そのままビルドしてください。ちなみに、デバッグ・リリースモードそれぞれ /MTd, /MT に設定されています。特に変更する必要はないです。 Debug, Release それぞれビルドを行うと zlib-1.2.6/contrib/vstudio/vc10/x86 ディレクトリに以下のディレクトリができていますMiniUnzipDebug, MiniZipDebug, TestZlibDebug, TestZlibDllDebug, ZlibStatDebug, ZlibDllDebug MiniUnzipRelease, MiniZipRelease, TestZlibDllRelease, TestZlibRelease, ZlibDllRelease, ZlibStatRelease ZlibDll○○ に.dll ファイル, ZlibStat○○ に.lib ファイルがそれぞれ出力されています。 エラーが出てる! testzlib プロジェクトをビルドしたときに、エラーが出た場合 2 zutil.obj error LNK2019 未解決の外部シンボル _gzflags@0 が関数 _zlibCompileFlags@0 で参照されました。 2 x86\TestZlibDebug\testzlib.exe fatal error LNK1120 外部参照 1 が未解決です。 testzlib プロジェクトのプロパティを開き、[構成プロパティ]- [リンカー]- [入力]追加の依存ファイルに"x86\ZlibStatDebug\zlibstat.lib" を追加します(Debug 時) Release 時も同様に"x86\ZlibStatRelease\zlibstat.lib" を追加しておいてください。 これでもう一度ビルドすると成功します。"x86\ZlibStatDebug\zlibstat.lib" または "x86\ZlibStatRelease\zlibstat.lib" が存在しないと上手くいきません zlibstat プロジェクトをビルドしてから行うと上手く行きます 関連リンク http //zlib.net/ - zlib 公式サイト
https://w.atwiki.jp/sampleisbest/pages/81.html
参考 シリコンバレー 24時 8086マシン語、ハンド・アセンブル実験(1) Assemble Programming Assembler/ForFun(x86_32) - Glamenv-Septzen.net Windows実行ファイルのバイナリ概要 (1/2):CodeZine MASMたかき協会 16bit 実行 32bit環境:可 64bit環境:DOSBoxや98エミュで可 ret メモ帳で作るCOMファイル hello16 LASMでhello out PC-98エミュレータとMASM masm32 MASM32でCOMファイルを作りDOSBoxで実行 dec1 WORD値を10進表示 hexout レジスタの内容を16進出力 small MASM32でEXEファイルを作る short 小さい16bitEXE 32bit 実行 64bit環境:可 hello VC++ 2010 ExpressでMASM hello2 VC++ 2013 ExpressでMASM hello3 VS 2017でMASM hello2019 VS 2019でMASM hello2019c VS 2019でコンソール print 書式出力 vprint 可変長引数対応の書式出力 startup コマンドラインの展開 add32 VS 2019 C++からの関数呼出 hello32 MASM32でメッセージボックス hello32c MASM32でコンソール helloasm libcmt.libを使ってみる uselibc libcmt.libを使ってみる2 WinApp Windowsアプリケーション 64bit hello64vs VS 2017でMASM add64 VS 2019 C++からの関数呼出 hello64c ML64でメッセージボックス hellocon ML64でコンソール test64 VC++とML64 extasm VC++からアセンブリ言語ルーチン利用 printf 書式コンソール出力 cpuid CPUID表示 FPU/MMX/SSE fpusse FPUとSSEのサンプル mmx1 MMXサンプル sse1 SSEサンプル
https://w.atwiki.jp/wiki7_ahr/pages/21.html
#blognavi MALLOC_CHECK_ 環境変数をセットしておけば、異なる、そして、なぜかよりスローなメモリ 管理関数群が選択され、よりエラーと、同一ポインタに関して1回以上free()が呼ばれる かどうかと、シングルバイト・バッファのオーバーフローについてチェックします。 MALLOC_CHECK_を2にセットすると、メモリ管理機構は問題を検出した時にabort()をコール します。 MALLOC_CHECK_を0にセットすると、あるメモリバグの検出により先に進めなくなってしまっ ている時に助かるはずです。エラーの追跡をそこでストップし、とりあえず先に進む事が 出来る様になるからです。 MALLOC_CHECK_を1にセットすると、まだ問題の有無が明確になっていなくて、何が起きて いるのかを知りたい(発生した事象を通知してほしい)時に役に立つでしょう。 MALLOC_CHECK_を2にセットすると、デバッガの内部でメモリ管理機構がエラーを検出した 時に、直ちに最寄りのポインタからバックトレースを取ったりするのには最も有用です。 関連リンク CとC++ メモリマネジメント バッファオーバーフローの回避 カテゴリ [メモリ管理] - trackback- 2006年03月14日 23 24 40 #blognavi
https://w.atwiki.jp/gen3/pages/19.html
KarmaLib 元ページはKarmaLib 0.9.1a。以下ランダムなメモ。 0.9.1aはJava2SE環境(1.5あるいは1.6)ではLITTLE_ENDIANのfidをJavaのデフォルトであるBIG_ENDIANで読み込んでしまい、この部分で失敗する。 PlaylistUtils.getPlaylistEntriesFromString(String playlistString) ... ByteBuffer bb = ByteBuffer.allocateDirect(playlist.length) .order(ByteOrder.LITTLE_ENDIAN); // これを追加 と PlaylistUtils.getPlaylistStringFromEntries(PlaylistEntry[] entries) ... ByteBuffer bb = ByteBuffer.allocate((8 * entries.length) + 4) .order(ByteOrder.LITTLE_ENDIAN); // これを追加 を直して、ユーザープログラム動作時に次のようにJavaVMのデフォルトエンコーディングをUTF-8にして、 System.setProperty("file.encoding", "UTF-8"); 以上で使えるはず。このデフォルトエンコーディングは、 KarmaClient.getDeviceSettings() の出力 { device_generation=1302852415, name=Rio Karma, capabilities=;read_content;utf8;rewrite_metadata;file_replace; playlists;root_playlist;played_statistics;, serial=0034373, max_playlist_entries=15000, codecs=;mp3;wma;vorbis;flac;wave;, recovery=0, device_id=0x5210, hwrev=0x4, storage_name=??????????????£????? ̄, rns_version=805016800, manufacturer=Rio Audio, firmware_version=1.68, rns_prefix=KRM } の中でcapabilities=の値にutf8とあればUTF-8に、その他の設定であればそれに合わせるのが正しいのだろうと思われる。 追加事項 PropertiesWrapper.[[java]] ... public void readPropertyFromByteArray( byte[] property ) { try { String temp = new String(property, "UTF-8"); という風に、強制的にUTF-8でエンコードしないとダメの様子。new Stringのデフォルトはfile.encodingで決まるんじゃないのかなあ。 dev.karma.lib.data.FileDetails#getRid() / setRid(String) RIDは、楽曲ファイルのID3タグ等を除いた楽曲本体データ部分について計算したMD5値でHEX文字列。ただし、データサイズが64KB超える場合は、データの最初と真ん中と最後を取り出して計算している。 このRIDは dev.karma.lib.util.FileUtils#calculateRid() で計算する。 dev.karma.lib.data.FileDetails#getOffset() / getTrailer() 楽曲ファイルのID3タグ等を除いたデータ部分のバイト位置。trailerはファイルの最後からの位置。 ID3タグに限って言えば、offsetがID3v2の長さに対応し、trailerがID3v1の長さ(128バイト固定)に対応する。APEタグには対応していない、つまり検知せずMP3データの一部として取り扱っている。 dev.karma.lib.data.FileDetails#getType() プレイリストなら"playlist"、楽曲ファイルなら"tune"が返る。 ちなみにメインのプレイリスト(プレイリストを含むプレイリスト)の場合、fid_generationやctimeがプロパティとして存在しない。これで普通のプレイリストと区別しているのではないかと推測される。 プレイリストのプロパティ プレイリストの場合に取得されるプロパティは次の通り。 プロパティ名 意味/内容 値の例 marked 不明 0 length playlistのバイト長 68 playlist fidの羅列となるバイナリデータを、iso-8859-1エンコーディング(要はASCIIの範囲外の文字もあるが普通のASCIIとして)16進エスケープ表示した文字列 ?\x02\x00\x00?\x02\x00\x00D?\??\x02\x00\x00D?\??\x02\x00\x00D?\?\x00\x03\x00\x00D?\?\x10\x03\x00\x00D?\? \x03\x00\x00D?\?0\x03\x00\x00D?\?`\x01\x00\x00D?\? fid ファイルの識別番号 7728 fid_generation fidの生成日時 2007/11/21 14 48 16 file_id 別のバージョンのfid相当と思われるが使われていない模様 0 play_count 再生回数らしいがプレイリストでは常に0 0 ctime ファイルの生成日時、「プレイリストのプレイリスト」ではこの項目がない 2007/11/21 14 48 16 tracknr ID3でのトラック番号 0 type ファイルタイプ(playlist/tune) playlist play_count_limit 古い楽曲から順次入れ替えていく機能で使用するための再生回数上限 0 title このファイルのタイトル アルバムタイトル 曲データのプロパティ プロパティ名 内容/意味 値の例 fid ファイル識別子 288 fid_generation fidの生成日時 2076/09/03 6 06 12 type ファイルタイプ tune length ファイルのバイト長 6223504 offset ID3v2タグの長さ 2058 trailer ID3v1タグの長さ 128 bitrate ビットレート vs192 samplerate 曲データのサンプリングレート(Hz) 44100 codec コーデック mp3 rid 曲データを一意に識別するための特殊な計算したMD5値 6a16b2bdf9750c3501e7386f229a4b57 play_count_limit 再生回数上限 0 play_count 再生回数 106 ctime ファイルの作成日時 2007/11/21 14 48 16 play_last 最終再生日時となっているが再生しても更新されない 2008/09/20 17 05 15 profile 不明 \x00\x00\x00\x00UUE\x05????\x01P?? ̄j??????????? ̄?????k\x00P\? profiler_version profileのバージョンと思われるが不明 1001 rms 不明 3583 stddev 不明 603 marked 不明 0 file_id 使われていないファイル識別子 0 duration 不明 259186 artist ID3の作曲者タグ Lyric by yukki♪ Composed by Azell genre ID3のジャンル Vocal source ID3タグのアルバム ニコ動 title ID3の曲タイトル BEST FRIENDS tracknr ID3のトラック番号 0 year ID3タグの年 2007
https://w.atwiki.jp/lockerroom/pages/13.html
ActiveX.ahk /* COM操作ライブラリby 流行らせるページ管理人 Ver 3β / ActiveX(){ global IID_IDispatch =GUID("{00020400-0000-0000-C000-000000000046}") IID_IUnknown =GUID("{00000000-0000-0000-C000-000000000046}") IID_NULL =GUID("{00000000-0000-0000-0000-000000000000}") IID_IConnectionPointContainer =GUID("{B196B284-BAB4-101A-B69C-00AA00341D07}") IID_IProvideClassInfo =GUID("{B196B283-BAB4-101A-B69C-00AA00341D07}") ;IID_IProvideClassInfo2 =GUID("{A6BC3AC0-DBAA-11CE-9DE3-00AA004BB851}") LOCALE_USER_DEFAULT =DllCall("kernel32.dll¥GetUserDefaultLCID") CoInitialize() } /* ********************************** 汎用メモリ管理 ********************************** / ;メモリを確保しポインタを返す Malloc(size,flag=0x40){ return DllCall("kernel32.dll¥GlobalAlloc","UInt",flag,"UInt",size,"UInt") } ;ポインタで指定されたメモリを解放する Free(p){ DllCall("kernel32.dll¥GlobalFree",UInt,p,UInt) } /* ********************************** GUID関連 ********************************** / ;CLSID文字列からGUID構造体を生成しアドレスを得る(仮) GUID(string){ size =DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",string,"Int",-1,"UInt",0,"Int",0) wstr =Malloc((size+1)*2) DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",string,"Int",-1,"UInt",wstr,"Int",(size+1)*2) ptr =Malloc(16) DllCall("ole32.dll¥CLSIDFromString","UInt",wstr,"UInt",ptr) Free(wstr) return ptr } ;ProgID文字列からGUID構造体を生成しアドレスを得る(仮) ProgID(string){ size =DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",string,"Int",-1,"UInt",0,"Int",0) wstr =Malloc((size+1)*2) DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",string,"Int",-1,"UInt",wstr,"Int",(size+1)*2) ptr =Malloc(16) DllCall("ole32.dll¥CLSIDFromProgID","UInt",wstr,"UInt",ptr) Free(wstr) return ptr } ;GUID構造体を文字列に変換 fromGUID(ByRef guid){ ptr =Malloc(80) DllCall("ole32.dll¥StringFromGUID2","UInt",guid,"UInt",ptr,"Int",80) res =wc2mb(ptr) Free(ptr) return res } /* ********************************** Unicode関連 ********************************** / ;文字列からにUnicodeへの変換を行う ;返り値はUnicode文字列へのポインタ mb2wc(mbstr){ size =(DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",mbstr,"Int",-1,"UInt",0,"Int",0)+1)*2 wstr =Malloc(size) DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",mbstr,"Int",-1,"UInt",wstr,"Int",size) return wstr } mb2wc_ref(ByRef mbstr){ size =(DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",mbstr,"Int",-1,"UInt",0,"Int",0)+1)*2 wstr =Malloc(size) DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",mbstr,"Int",-1,"UInt",wstr,"Int",size) return wstr } ;UnicodeからAnsi文字列への変換を行う ;返り値は文字列 wc2mb(wstr){ size =DllCall("kernel32.dll¥WideCharToMultiByte","UInt",0,"UInt",0,"UInt",wstr,"Int",-1,"UInt",0,"Int",0,"UInt",0,"UInt",0) VarSetCapacity(mbstr,size) DllCall("kernel32.dll¥WideCharToMultiByte","UInt",0,"UInt",0,"UInt",wstr,"Int",-1,"Str",mbstr,"Int",size,"UInt",0,"UInt",0) return mbstr } wc2mb_ref(wstr,ByRef mbstr){ size =DllCall("kernel32.dll¥WideCharToMultiByte","UInt",0,"UInt",0,"UInt",wstr,"Int",-1,"UInt",0,"Int",0,"UInt",0,"UInt",0) VarSetCapacity(mbstr,size) DllCall("kernel32.dll¥WideCharToMultiByte","UInt",0,"UInt",0,"UInt",wstr,"Int",-1,"Str",mbstr,"Int",size,"UInt",0,"UInt",0) return size } /* ********************************** COM汎用 ********************************** / CoInitialize(){ return DllCall("ole32.dll¥CoInitialize","UInt",0,"UInt") } CoUninitialize(){ return DllCall("ole32.dll¥CoUninitialize","UInt",0,"UInt") } OleInitialize(){ return DllCall("ole32.dll¥OleInitialize","UInt",0,"UInt") } OleUninitialize(){ return DllCall("ole32.dll¥OleUninitialize","UInt",0,"UInt") } CoTaskMemAlloc(size){ return DllCall("ole32.dll¥CoTaskMemAlloc","UInt",size,"UInt") } CoTaskMemFree(ptr){ return DllCall("ole32.dll¥CoTaskMemFree","UInt",ptr,"UInt") } M(ByRef ip,idx=0){ return NumGet(NumGet(ip+0)+4*idx) } QueryInterface(pObj,strIID=""){ global IID_IDispatch guid =0 if(strIID=""){ IID =IID_IDispatch }else if(StrLen(strIID)=38){ IID =GUID(strIID) }else{ IID =strIID } res =0 ErrorLevel =DllCall(M(pObj,0),"UInt",pObj,"UInt",IID,"UIntP",res) return res } AddRef(pObj){ if(pObj){ DllCall(M(pObj,1),"UInt",pObj) } return pObj } Release(pObj){ if(pObj){ return DllCall(M(pObj,2),"UInt",pObj) } } ReleaseL(p1,p2=-1,p3=-1,p4=-1,p5=-1,p6=-1,p7=-1,p8=-1,p9=-1){ format =A_FormatInteger SetFormat,Integer,D Loop,10{ if(p%A_Index%!=-1){ Release(p%A_Index%) } } SetFormat,Integer,%format% } /* ********************************** VARIANT関連 ********************************** / ;Ansi文字列をBSTR形式に変換する toBSTR(str){ oc =mb2wc(str) res =DllCall("oleaut32.dll¥SysAllocString","UInt",oc,"UInt") Free(oc) return res } ;BSTRをAnsi文字列に変換する fromBSTR(bstr){ return wc2mb(bstr) } ;BSTRを解放する(VariantClear内でやってくれるはずなので多分不要) freeBSTR(bstr,get=0){ if(get!=0){ wc2mb_ref(bstr,res) }else{ res= } DllCall("oleaut32.dll¥SysFreeString","UInt",bstr) return res } vNull(){ return 0x7FFFFFFF00000000 } vObj(obj){ return 0x7FFFFFFF00000000 | obj } ;VARIANTに変換(typeには変換したい型を指定 ;settypeを指定すると、型変換した上で、型を示す値としてsettypeで指定した型を格納する toVariant(value,variant=0,type=0x08,settype=-1){ global LOCALE_USER_DEFAULT ;格納先初期化 if(variant=0){ dest =Malloc(16) }else{ dest =variant } DllCall("oleaut32.dll¥VariantInit","UInt",dest) if(type=0x08){ if(value 32 = 0x7FFFFFFF){ if(value-0x7FFFFFFF00000000=0){ ;VT_NULL NumPut(0x01,dest+0,0,"UShort") }else{ ;VT_DISPATCH NumPut(0x09,dest+0,0,"UShort") NumPut(value - 0x7FFFFFFF00000000,dest+8,0) } }else{ ;文字列の場合 NumPut(0x08,dest+0,0,"UShort") NumPut(toBSTR(value),dest+8,0) } }else{ ;それ以外の型の場合 tmp =toVariant(value) DllCall("oleaut32.dll¥VariantChangeTypeEx","UInt",dest,"UInt",tmp,"UInt",LOCALE_USER_DEFAULT,"UShort",0,"UShort",type) if(settype!=-1){ NumPut(settype,dest+0,0,"UShort") } vFree(tmp) } return dest } ;VARIANTに格納された内容を通常のAutoHotkey変数として取得 ;rawsizeが1,2,4の場合、格納されている生の値を取得 ;rawsizeが0の場合、文字列に変換して取得 fromVariant(var,rawsize=0){ global LOCALE_USER_DEFAULT if(rawsize=0){ type =NumGet(var+0,0,"UShort") if((type=9)||(type=13)){ ;COMオブジェクト pObj =NumGet(var+8) AddRef(pObj) return pObj }else if(type 0xFF){ ;ポインタもしくは配列(暫定) return NumGet(var+8) }else{ ;VT_BSTRに変換 var2 =Malloc(16) DllCall("oleaut32.dll¥VariantInit","UInt",var2) DllCall("oleaut32.dll¥VariantChangeTypeEx","UInt",var2,"UInt",var,"UInt",LOCALE_USER_DEFAULT,"UShort",0,"UShort",0x8) ;値をAnsiに変換 wc2mb_ref(NumGet(var2+8),res) vFree(var2) return res } }else if(rawsize=1){ return NumGet(var+8,0,"UChar") }else if(rawsize=2){ return NumGet(var+8,0,"UShort") }else if(rawsize=4){ return NumGet(var+8) }else{ return fromVariant(var,0) } } ;VARIANTを解放(getに-1以外を指定すると、値を取得して返す) vFree(ByRef var,get=-1){ if(get!=-1){ res =fromVariant(var,get) }else{ res =0 } DllCall("oleaut32.dll¥VariantClear","UInt",var) Free(var) return res } /* ********************************** IDispatch用 ********************************** / ;オブジェクトを生成する CreateObject(clsid,iid="",CLSCTX=5){;CLSCTX_SERVER global IID_IDispatch if(!IID_IDispatch){ ActiveX() } guid =0 if(RegExMatch(clsid,"^¥{[¥-0-9a-fA-F]{36}¥}$")){ guid =GUID(clsid) }else{ guid =ProgID(clsid) } if(iid=""){ iid2 =IID_IDispatch }else{ iid2 =GUID(iid) } ppRes =0 el =DllCall("ole32.dll¥CoCreateInstance","UInt",guid,"UInt",0,"UInt",CLSCTX,"UInt",iid2,"UIntP",ppRes,"UInt") Free(guid) if(iid2!=IID_IDispatch){ Free(iid2) } ErrorLevel =el return ppRes } ;objが持つnameメンバのDispatchIDを得る GetDispID(ByRef obj,name){ global IID_NULL,LOCALE_USER_DEFAULT wName =mb2wc_ref(name) dispid =0 DllCall(M(obj,5),"UInt",obj,"UInt",IID_NULL,"UIntP",wName,"UInt",1,"UInt",LOCALE_USER_DEFAULT,"UIntP",dispid,"UInt") Free(wName) return dispid } ;引数からDISPPARAMSを生成 CreateParam(ByRef p1, ByRef p2, ByRef p3, ByRef p4, ByRef p5, ByRef p6, ByRef p7, ByRef p8, ByRef p9, ByRef p10){ ;引数を数える(0xFFFFFFFFFFFFFFFFの前までが与えられた引数) num =0 format =A_FormatInteger SetFormat,Integer,D Loop,10{ if(p%A_Index%=0xFFFFFFFFFFFFFFFF){ break } num++ } ;num個のVARIANTARG配列を作成 if(num=0){ pvArgs =0 }else{ pvArgs =Malloc(16*num) ptr =pvArgs+16*(num-1) ;引数をセットしていく Loop,%num%{ toVariant(p%A_Index%,ptr) ptr-=16 } } SetFormat,Integer,%format% ;DISPPARAMS作成 res =Malloc(16) NumPut(pvArgs,res+0) NumPut(num,res+8) return res } ;DISPPARAMSを解放 FreeParam(ByRef params){ num =NumGet(params+8) pvArgs =NumGet(params+0) pvNArgs =NumGet(params+4) ;VARIANTARGの解放処理 ptr =pvArgs Loop,%num%{ vFree(ptr) ptr+=16 } ;VARIANTARG自体の解放 Free(ptr) ;rgdispidNamedArgsの解放 if(pvNArgs!=0){ Free(pvNArgs) } ;本体メモリ解放 Free(params) } Invoke(ByRef pObj,ByRef dispid,mode,ByRef params){ global IID_NULL,LOCALE_USER_DEFAULT pvRes =Malloc(16) DllCall("oleaut32.dll¥VariantInit",UInt,pvRes) DllCall(M(pObj,6),UInt,pObj,UInt,dispid,UInt,IID_NULL,UInt,LOCALE_USER_DEFAULT,UInt,mode,UInt,params,UInt,pvRes,UInt,0,UInt,0,UInt) return pvRes } inv(obj,name,p1=0xFFFFFFFFFFFFFFFF,p2=0xFFFFFFFFFFFFFFFF,p3=0xFFFFFFFFFFFFFFFF,p4=0xFFFFFFFFFFFFFFFF,p5=0xFFFFFFFFFFFFFFFF,p6=0xFFFFFFFFFFFFFFFF,p7=0xFFFFFFFFFFFFFFFF,p8=0xFFFFFFFFFFFFFFFF,p9=0xFFFFFFFFFFFFFFFF,p10=0xFFFFFFFFFFFFFFFF){ if((dispid =GetDispID(obj,name))!=0){ params =CreateParam(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) pvRes =Invoke(obj,dispid,1,params) FreeParam(params) return vFree(pvRes,0) } } gp(obj,name,p1=0xFFFFFFFFFFFFFFFF,p2=0xFFFFFFFFFFFFFFFF,p3=0xFFFFFFFFFFFFFFFF,p4=0xFFFFFFFFFFFFFFFF,p5=0xFFFFFFFFFFFFFFFF,p6=0xFFFFFFFFFFFFFFFF,p7=0xFFFFFFFFFFFFFFFF,p8=0xFFFFFFFFFFFFFFFF,p9=0xFFFFFFFFFFFFFFFF,p10=0xFFFFFFFFFFFFFFFF){ if((dispid =GetDispID(obj,name))!=0){ params =CreateParam(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) pvRes =Invoke(obj,dispid,2,params) FreeParam(params) return vFree(pvRes,0) } } pp(obj,name,p1=0xFFFFFFFFFFFFFFFF,p2=0xFFFFFFFFFFFFFFFF,p3=0xFFFFFFFFFFFFFFFF,p4=0xFFFFFFFFFFFFFFFF,p5=0xFFFFFFFFFFFFFFFF,p6=0xFFFFFFFFFFFFFFFF,p7=0xFFFFFFFFFFFFFFFF,p8=0xFFFFFFFFFFFFFFFF,p9=0xFFFFFFFFFFFFFFFF,p10=0xFFFFFFFFFFFFFFFF){ if((dispid =GetDispID(obj,name))!=0){ params =CreateParam(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) ;rgdispidNamedArgsのセット namedArgs =Malloc(4) NumPut(namedArgs,params+4) NumPut(0xFFFFFFFD,namedArgs+0) NumPut(1,params+12) pvRes =Invoke(obj,dispid,4,params) FreeParam(params) return vFree(pvRes) } } /* ********************************** イベントシンク用コールバック関数 ********************************** / GuidIsEqual(guid1,guid2){ return DllCall("MSVCRT.dll¥memcmp","UInt",guid1,"UInt",guid2,"UInt",16)=0 } EVENTSINK_QueryInterface(pEv,iid,ppv){ global if(GuidIsEqual(iid,NumGet(pEv+8))||GuidIsEqual(iid,IID_IDispatch)||GuidIsEqual(iid,IID_IUnknown)){ NumPut(pEv,ppv+0) DllCall(M(pEv,1),"UInt",pEv) return 0 } NumPut(0,ppv+0) return 0x80004002 } EVENTSINK_AddRef(pEv){ cRef =NumGet(pEv+4) cRef++ NumPut(cRef,pEv+4) return cRef } EVENTSINK_Release(pEv){ cRef =NumGet(pEv+4) cRef-- NumPut(cRef,pEv+4) if(cRef==0){ EVENTSINK_Destructor(pEv) } return cRef } EVENTSINK_GetTypeInfoCount(pEv,pct){ NumPut(0,pct+0) return 0 } EVENTSINK_GetTypeInfo(pEv,info,lcid,pInfo){ return 0x8002000B;DISP_E_BADINDEX } EVENTSINK_GetIDsOfNames(pEv,riid,szNames,cNames,lcid,pDispID){ return 0x80020006;DISP_E_UNKNOWNNAME } EVENTSINK_Invoke(pEv,dispid,riid,lcid,wFlags,params,pvRes,exinf,argerr){ pTypeInfo =NumGet(pEv+24) ;GetNames hr =DllCall(M(pTypeInfo,7),"UInt",pTypeInfo, "UInt",dispid, "UIntP",bstr, "UInt",1, "UIntP",count) if(hr!=0){ return 0 } wc2mb_ref(bstr,ev) cb =GetOleEventCallback(NumGet(pEv+12),ev) if(cb){ DllCall(cb,"UInt",NumGet(pEv+28), "UInt",params, "UInt",pvRes) } } EVENTSINK_Constructor(){ static vtEventSink if(!vtEventSink){ vtEventSink =Malloc(28) NumPut(RegisterCallback("EVENTSINK_QueryInterface"),vtEventSink+0) NumPut(RegisterCallback("EVENTSINK_AddRef"),vtEventSink+4) NumPut(RegisterCallback("EVENTSINK_Release"),vtEventSink+8) NumPut(RegisterCallback("EVENTSINK_GetTypeInfoCount"),vtEventSink+12) NumPut(RegisterCallback("EVENTSINK_GetTypeInfo"),vtEventSink+16) NumPut(RegisterCallback("EVENTSINK_GetIDsOfNames"),vtEventSink+20) NumPut(RegisterCallback("EVENTSINK_Invoke"),vtEventSink+24) } pEv =Malloc(32) NumPut(vtEventSink,pEv+0) return pEv } EVENTSINK_Destructor(pEv){ Release(NumGet(pEv+28)) Free(pEv) } /* ********************************** コネクト用のインターフェイスIDを検索 ********************************** / find_iid(ByRef obj,ByRef itf,ByRef iid,ByRef refPTypeInfo=0xFFFFFFFFFFFFFFFF){ global LOCALE_USER_DEFAULT ;GetTypeInfo hr =DllCall(M(disp,4),"UInt",obj, "UInt",0, "UInt",LOCALE_USER_DEFAULT, "UIntP",pTypeInfo) if(hr!=0){ return hr } ;GetContainingTypeLib hr =DllCall(M(pTypeInfo,18),"UInt",pTypeInfo, "UIntP",pTypeLib, "UIntP",index) Release(pTypeInfo) if(hr!=0){ return hr } if(!itf){ ;GetTypeInfoOfGuid hr =DllCall(M(pTypeLib,5),"UInt",pTypeLib, "UIntP",iid, "UIntP",refPTypeInfo) Release(pTypeLib) return hr } count =DllCall(M(pTypeLib,3),"UInt",pTypeLib);GetTypeInfoCount found =0 index =0 Loop,%count%{ hr =DllCall(M(pTypeLib,4),"UInt",pTypeLib, "UInt",index, "UIntP",pTypeInfo);GetTypeInfo if(hr!=0){ break } hr =DllCall(M(pTypeInfo,3),"UInt",pTypeInfo, "UIntP",pTypeAttr);GetTypeAttr if(hr!=0){ Release(pTypeInfo) break } if(NumGet(pTypeAttr+40)==5){;typekind==TKIND_COCLASS cTypes =NumGet(pTypeAttr+48,"UShort");cImplTypes type =0 Loop,%cTypes%{ hr =DllCall(M(pTypeInfo,8),"UInt",pTypeInfo, "UInt",type, "UIntP",RefType);GetRefTypeOfImplType if(hr!=0){ break } hr =DllCall(M(pTypeInfo,14),"UInt",pTypeInfo, "UInt",RefType, "UIntP",pImplTypeInfo);GetRefTypeInfo if(hr!=0){ break } ;GetDocumentation hr =DllCall(M(pImplTypeInfo,12),"UInt",pImplTypeInfo, "Int",-1, "UIntP",bstr, "UInt",0, "UInt",0, "UInt",0) if(hr!=0){ Release(pImplTypeInfo) break } wc2mb_ref(bstr,str) if(str==itf){ ;GetTypeAttr if(DllCall(M(pImplTypeInfo,3),"UInt",pImplTypeInfo, "UIntP",pImplTypeAttr)=0){ found =1 iid =Malloc(16) DllCall("kernel32.dll¥RtlMoveMemory", "UInt",iid, "UInt",pImplTypeAttr, "UInt",16) if(refPTypeInfo!=0xFFFFFFFFFFFFFFFF){ refPTypeInfo =pImplTypeInfo AddRef(pImplTypeInfo) } ;ReleaseTypeAttr DllCall(M(pImplTypeInfo,3),"UInt",pImplTypeInfo, "UInt",pImplTypeAttr) } } Release(pImplTypeInfo) if(found||(hr!=0)){ break } type++ } } hr =DllCall(M(pTypeInfo,3),"UInt",pTypeInfo, "UInt",pTypeAttr);ReleaseTypeAttr Release(pTypeInfo) if(found||(hr!=0)){ break } index++ } Release(pTypeLib) if(!found){ return 0x80004002 }else{ return hr } } find_default_source(ByRef obj,ByRef iid,ByRef refPTypeInfo){ global IID_IProvideClassInfo;,IID_IProvideClassInfo2 /* pProvideClassInfo2 =QueryInterface(obj,IID_IProvideClassInfo2) if(ErrorLevel________==0){ ;GetGUID hr =DllCall(M(pProvideClassInfo2,4),"UInt",pProvideClassInfo2, "UInt",1, "UIntP",iid) Release(pProvideClassInfo2) return find_iid(obj,"",iid,refPTypeInfo) } / pProvideClassInfo =QueryInterface(obj,IID_IProvideClassInfo) if(ErrorLevel!=0){ return ErrorLevel } ;GetClassInfo hr =DllCall(M(pProvideClassInfo,3),"UInt",pProvideClassInfo, "UIntP",pTypeInfo) Release(pProvideClassInfo) if(hr!=0){ return hr } ;GetTypeAttr hr =DllCall(M(pTypeInfo,3),"UInt",pTypeInfo, "UIntP",pTypeAttr) if(hr!=0){ Release(pTypeInfo) return hr } cTypes =NumGet(pTypeAttr+48,"UShort");cImplTypes type =0 Loop,%cTypes%{ hr =DllCall(M(pTypeInfo,9),"UInt",pTypeInfo, "UInt",type, "UIntP",iFlags);GetImplTypeFlags if(hr!=0){ continue } if((iFlags 0x3)=0x3){;((iFlags IMPLTYPEFLAG_FDEFAULT) (iFlags IMPLTYPEFLAG_FSOURCE)) hr =DllCall(M(pTypeInfo,8),"UInt",pTypeInfo, "UInt",type, "UIntP",RefType);GetRefTypeOfImplType if(hr!=0){ continue } hr =DllCall(M(pTypeInfo,14),"UInt",pTypeInfo, "UInt",RefType, "UIntP",refPTypeInfo);GetRefTypeInfo if(hr!=0){ break } } type++ } DllCall(M(pTypeInfo,3),"UInt",pTypeInfo, "UInt",pTypeAttr);ReleaseTypeAttr Release(pTypeInfo) if(!refPTypeInfo){ if(hr==0){ return 0x8000FFFF }else{ return hr } } if(DllCall(M(refPTypeInfo,3),"UInt",refPTypeInfo, "UIntP",pTypeAttr)=0){;GetTypeAttr iid =Malloc(16) DllCall("kernel32.dll¥RtlMoveMemory", "UInt",iid, "UInt",pTypeAttr, "UInt",16) DllCall(M(refPTypeInfo,3),"UInt",refPTypeInfo, "UInt",pTypeAttr);ReleaseTypeAttr }else{ Release(refPTypeInfo) refPTypeInfo ="" } return hr } EntryOleEventPrefix(ByRef prefix){ global static OleEventCount=0 if(OleEventID_%prefix%){ return OleEventID_%prefix% }else{ OleEventID_%prefix% =OleEventCount OleEventPrefix_%OleEventCount% =prefix return OleEventCount++ } } GetOleEventCallback(id,ByRef evt){ global local prefix,cb prefix =OleEventPrefix_%id% if(prefix){ if(OleEventCallback_%prefix%%evt%){ return OleEventCallback_%prefix%%evt% } cb =RegisterCallback(prefix . evt) if(cb){ OleEventCallback_%prefix%%evt% =cb return cb } } } ConnectObject(obj,prefix,itf=0xFFFFFFFFFFFFFFFF){ global IID_IConnectionPointContainer if(itf==0xFFFFFFFFFFFFFFFF){ hr =find_default_source(obj,iid,pTypeInfo) }else{ hr =find_iid(obj,itf,iid,pTypeInfo) } if(hr!=0){ ErrorLevel =hr return 0 } pContainer =QueryInterface(obj,IID_IConnectionPointContainer) if(ErrorLevel!=0){ Release(pTypeInfo) return 0 } ;FindConnectionPoint hr =DllCall(M(pContainer,4),"UInt",pContainer, "UInt",iid, "UIntP",pConnectionPoint) Release(pContainer) if(hr!=0){ Release(pTypeInfo) return 0 } pIEV =EVENTSINK_Constructor() NumPut(iid,pIEV+8) ;Advise hr =DllCall(M(pConnectionPoint,5),"UInt",pConnectionPoint, "UInt",pIEV, "UIntP",dwCookie) if(hr!=0){ return 0 } AddRef(obj) evid =EntryOleEventPrefix(prefix) NumPut(evid,pIEV+12) NumPut(dwCookie,pIEV+16) NumPut(pConnectionPoint,pIEV+20) NumPut(pTypeInfo,pIEV+24) NumPut(obj,pIEV+28) } evArgc(ByRef para){ return NumGet(para+8) } evArgv(ByRef para,idx){ num =NumGet(para+8) if(idx num){ return fromVariant(NumGet(para+0)+(num-1-idx)*16) } } evReturn(ByRef res,value){ toVariant(value,res) } /* ********************************** ディスパッチオブジェクト作成 ********************************** / DISPATCH_QueryInterface(ptr,iid,ppv){ global if(GuidIsEqual(iid,IID_IDispatch)||GuidIsEqual(iid,IID_IUnknown)){ NumPut(ptr,ppv+0) DllCall(M(ptr,1),"UInt",ptr) return 0 }else{ NumPut(0,ppv+0) return 0x80004002 } } DISPATCH_AddRef(ptr){ cRef =NumGet(ptr+4) cRef++ NumPut(cRef,ptr+4) return cRef } DISPATCH_Release(ptr){ cRef =NumGet(ptr+4) cRef-- NumPut(cRef,ptr+4) if(cRef==0){ Free(ptr) } return cRef } DISPATCH_GetTypeInfoCount(ptr,pct){ NumPut(0,pct+0) return 0 } DISPATCH_GetTypeInfo(ptr,info,lcid,pInfo){ return 0x8002000B;DISP_E_BADINDEX } DISPATCH_GetIDsOfNames(ptr,riid,pszNames,cNames,lcid,pDispID){ wc2mb_ref(NumGet(pszNames+0),name) hr =GetOleMethodCallback(NumGet(ptr+12),name,cb) NumPut(cb,pDispID+0) return hr } DISPATCH_Invoke(ptr,dispid,riid,lcid,wFlags,params,pvRes,exinf,argerr){ DllCall(dispid,"UInt",ptr, "UInt",params, "UInt",pvRes, "UInt",wFlags) return 0 } EntryOleMethodsPrefix(ByRef prefix,ByRef id){ global static OleMethodsCount=0 if(OleMethodsID_%prefix%){ id =OleMethodsID_%prefix% }else{ OleMethodsID_%prefix% =OleMethodsCount OleMethodsPrefix_%OleMethodsCount% =prefix id =OleMethodsCount++ } } GetOleMethodCallback(id,ByRef name,ByRef cb){ global local prefix cb =0 prefix =OleMethodsPrefix_%id% if(prefix){ if(OleMethodCallback_%prefix%%name%){ cb =OleMethodCallback_%prefix%%name% return 0 }else{ cb =RegisterCallback(prefix . name) if(cb){ OleMethodCallback_%prefix%%name% =cb return 0 }else{ return 0x80020006 } } } } CreateDispatchObject(prefix,exsize=0){ global IID_IDispatch static vtDispatch if(!vtDispatch){ vtDispatch =Malloc(28) NumPut(RegisterCallback("DISPATCH_QueryInterface"),vtDispatch+0) NumPut(RegisterCallback("DISPATCH_AddRef"),vtDispatch+4) NumPut(RegisterCallback("DISPATCH_Release"),vtDispatch+8) NumPut(RegisterCallback("DISPATCH_GetTypeInfoCount"),vtDispatch+12) NumPut(RegisterCallback("DISPATCH_GetTypeInfo"),vtDispatch+16) NumPut(RegisterCallback("DISPATCH_GetIDsOfNames"),vtDispatch+20) NumPut(RegisterCallback("DISPATCH_Invoke"),vtDispatch+24) } EntryOleMethodsPrefix(prefix,id) ptr =Malloc(12+exsize) NumPut(vtDispatch,ptr+0) NumPut(IID_IDispatch,ptr+8) NumPut(id,ptr+12) return ptr }
https://w.atwiki.jp/thesimssocial/pages/25.html
スキルのアンロック・家具の組み立て等に必要なマテリアルリスト一覧 画像クリックで詳細ページに飛びます 記入されてない入手法をご存知でしたらコメントにお願いします スキルで入手可能 Amplifier Relaxation Buzz Entertainment Metronome Groove Muse Sheet Music Coffee Beans Saute Pan Mixing Bowl Pastry Graphs Paper Typewriter Ribbon Cloth Rubber Glove Duster Paint.pngPaint Light Box Landscape Painting Pencil Ruler Graphics Tablet Water Bottle Peach Witches Hat Trick and Treat Candy Canes Egg Bowl of flour Plans Guitar Pick Guitar String Culture 食事、衛生、睡眠、修理、掃除で入手可能 Butter pat Nutty Snackbar Dunkin Donuts Coffee Beans Delicious Morsel Leftovers Water Rubber Duckie Soapsuds Sponge Soft Pillow Night Cap Dreams Cloth Duster Rubber Glove Wrench Hammer Nails Apple 自宅の家具を使用 Entertainment Relaxation Buzz Toad Water Bottle Peach 自宅庭(一部隣人)から入手可能 Bling Herbs Muse Shell Driftwood Palm Leaf Love Goodwill Glass Eyes Ornaments Silver Bells Gold Star Holly Wreath Playing Card Dunkin Donuts Boost Fear Veggies Snail Test tubes Mice Test tubes 隣人から入手可能(会話/家具) Goodwill Love Fury Shell Lemon Slice Spoonful of sugar Joker Card Dice 入手方法が特殊な物 Metronome Trick and Treat コメント Wrench、Hammer、Nailsですが、アイテム「G King Counter」でのCookingスキル上げでも出現しました -- 名無しさん (2012-04-04 22 21 08) 適応しました、情報どもです~ -- 管理人 (2012-04-05 19 55 26) 名前 コメント
https://w.atwiki.jp/lockerroom/pages/14.html
/* COM操作ライブラリby 流行らせるページ管理人 Ver 3β */ ActiveX(){ global IID_IDispatch =GUID("{00020400-0000-0000-C000-000000000046}") IID_IUnknown =GUID("{00000000-0000-0000-C000-000000000046}") IID_NULL =GUID("{00000000-0000-0000-0000-000000000000}") IID_IConnectionPointContainer =GUID("{B196B284-BAB4-101A-B69C-00AA00341D07}") IID_IProvideClassInfo =GUID("{B196B283-BAB4-101A-B69C-00AA00341D07}") ;IID_IProvideClassInfo2 =GUID("{A6BC3AC0-DBAA-11CE-9DE3-00AA004BB851}") LOCALE_USER_DEFAULT =DllCall("kernel32.dll¥GetUserDefaultLCID") CoInitialize() } /* ********************************** 汎用メモリ管理 ********************************** */ ;メモリを確保しポインタを返す Malloc(size,flag=0x40){ return DllCall("kernel32.dll¥GlobalAlloc","UInt",flag,"UInt",size,"UInt") } ;ポインタで指定されたメモリを解放する Free(p){ DllCall("kernel32.dll¥GlobalFree",UInt,p,UInt) } /* ********************************** GUID関連 ********************************** */ ;CLSID文字列からGUID構造体を生成しアドレスを得る(仮) GUID(string){ size =DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",string,"Int",-1,"UInt",0,"Int",0) wstr =Malloc((size+1)*2) DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",string,"Int",-1,"UInt",wstr,"Int",(size+1)*2) ptr =Malloc(16) DllCall("ole32.dll¥CLSIDFromString","UInt",wstr,"UInt",ptr) Free(wstr) return ptr } ;ProgID文字列からGUID構造体を生成しアドレスを得る(仮) ProgID(string){ size =DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",string,"Int",-1,"UInt",0,"Int",0) wstr =Malloc((size+1)*2) DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",string,"Int",-1,"UInt",wstr,"Int",(size+1)*2) ptr =Malloc(16) DllCall("ole32.dll¥CLSIDFromProgID","UInt",wstr,"UInt",ptr) Free(wstr) return ptr } ;GUID構造体を文字列に変換 fromGUID(ByRef guid){ ptr =Malloc(80) DllCall("ole32.dll¥StringFromGUID2","UInt",guid,"UInt",ptr,"Int",80) res =wc2mb(ptr) Free(ptr) return res } /* ********************************** Unicode関連 ********************************** */ ;文字列からにUnicodeへの変換を行う ;返り値はUnicode文字列へのポインタ mb2wc(mbstr){ size =(DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",mbstr,"Int",-1,"UInt",0,"Int",0)+1)*2 wstr =Malloc(size) DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",mbstr,"Int",-1,"UInt",wstr,"Int",size) return wstr } mb2wc_ref(ByRef mbstr){ size =(DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",mbstr,"Int",-1,"UInt",0,"Int",0)+1)*2 wstr =Malloc(size) DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",mbstr,"Int",-1,"UInt",wstr,"Int",size) return wstr } ;UnicodeからAnsi文字列への変換を行う ;返り値は文字列 wc2mb(wstr){ size =DllCall("kernel32.dll¥WideCharToMultiByte","UInt",0,"UInt",0,"UInt",wstr,"Int",-1,"UInt",0,"Int",0,"UInt",0,"UInt",0) VarSetCapacity(mbstr,size) DllCall("kernel32.dll¥WideCharToMultiByte","UInt",0,"UInt",0,"UInt",wstr,"Int",-1,"Str",mbstr,"Int",size,"UInt",0,"UInt",0) return mbstr } wc2mb_ref(wstr,ByRef mbstr){ size =DllCall("kernel32.dll¥WideCharToMultiByte","UInt",0,"UInt",0,"UInt",wstr,"Int",-1,"UInt",0,"Int",0,"UInt",0,"UInt",0) VarSetCapacity(mbstr,size) DllCall("kernel32.dll¥WideCharToMultiByte","UInt",0,"UInt",0,"UInt",wstr,"Int",-1,"Str",mbstr,"Int",size,"UInt",0,"UInt",0) return size } /* ********************************** COM汎用 ********************************** */ CoInitialize(){ return DllCall("ole32.dll¥CoInitialize","UInt",0,"UInt") } CoUninitialize(){ return DllCall("ole32.dll¥CoUninitialize","UInt",0,"UInt") } OleInitialize(){ return DllCall("ole32.dll¥OleInitialize","UInt",0,"UInt") } OleUninitialize(){ return DllCall("ole32.dll¥OleUninitialize","UInt",0,"UInt") } CoTaskMemAlloc(size){ return DllCall("ole32.dll¥CoTaskMemAlloc","UInt",size,"UInt") } CoTaskMemFree(ptr){ return DllCall("ole32.dll¥CoTaskMemFree","UInt",ptr,"UInt") } M(ByRef ip,idx=0){ return NumGet(NumGet(ip+0)+4*idx) } QueryInterface(pObj,strIID=""){ global IID_IDispatch guid =0 if(strIID=""){ IID =IID_IDispatch }else if(StrLen(strIID)=38){ IID =GUID(strIID) }else{ IID =strIID } res =0 ErrorLevel =DllCall(M(pObj,0),"UInt",pObj,"UInt",IID,"UIntP",res) return res } AddRef(pObj){ if(pObj){ DllCall(M(pObj,1),"UInt",pObj) } return pObj } Release(pObj){ if(pObj){ return DllCall(M(pObj,2),"UInt",pObj) } } ReleaseL(p1,p2=-1,p3=-1,p4=-1,p5=-1,p6=-1,p7=-1,p8=-1,p9=-1){ format =A_FormatInteger SetFormat,Integer,D Loop,10{ if(p%A_Index%!=-1){ Release(p%A_Index%) } } SetFormat,Integer,%format% } /* ********************************** VARIANT関連 ********************************** */ ;Ansi文字列をBSTR形式に変換する toBSTR(str){ oc =mb2wc(str) res =DllCall("oleaut32.dll¥SysAllocString","UInt",oc,"UInt") Free(oc) return res } ;BSTRをAnsi文字列に変換する fromBSTR(bstr){ return wc2mb(bstr) } ;BSTRを解放する(VariantClear内でやってくれるはずなので多分不要) freeBSTR(bstr,get=0){ if(get!=0){ wc2mb_ref(bstr,res) }else{ res= } DllCall("oleaut32.dll¥SysFreeString","UInt",bstr) return res } vNull(){ return 0x7FFFFFFF00000000 } vObj(obj){ return 0x7FFFFFFF00000000 | obj } ;VARIANTに変換(typeには変換したい型を指定 ;settypeを指定すると、型変換した上で、型を示す値としてsettypeで指定した型を格納する toVariant(value,variant=0,type=0x08,settype=-1){ global LOCALE_USER_DEFAULT ;格納先初期化 if(variant=0){ dest =Malloc(16) }else{ dest =variant } DllCall("oleaut32.dll¥VariantInit","UInt",dest) if(type=0x08){ if(value 32 = 0x7FFFFFFF){ if(value-0x7FFFFFFF00000000=0){ ;VT_NULL NumPut(0x01,dest+0,0,"UShort") }else{ ;VT_DISPATCH NumPut(0x09,dest+0,0,"UShort") NumPut(value - 0x7FFFFFFF00000000,dest+8,0) } }else{ ;文字列の場合 NumPut(0x08,dest+0,0,"UShort") NumPut(toBSTR(value),dest+8,0) } }else{ ;それ以外の型の場合 tmp =toVariant(value) DllCall("oleaut32.dll¥VariantChangeTypeEx","UInt",dest,"UInt",tmp,"UInt",LOCALE_USER_DEFAULT,"UShort",0,"UShort",type) if(settype!=-1){ NumPut(settype,dest+0,0,"UShort") } vFree(tmp) } return dest } ;VARIANTに格納された内容を通常のAutoHotkey変数として取得 ;rawsizeが1,2,4の場合、格納されている生の値を取得 ;rawsizeが0の場合、文字列に変換して取得 fromVariant(var,rawsize=0){ global LOCALE_USER_DEFAULT if(rawsize=0){ type =NumGet(var+0,0,"UShort") if((type=9)||(type=13)){ ;COMオブジェクト pObj =NumGet(var+8) AddRef(pObj) return pObj }else if(type 0xFF){ ;ポインタもしくは配列(暫定) return NumGet(var+8) }else{ ;VT_BSTRに変換 var2 =Malloc(16) DllCall("oleaut32.dll¥VariantInit","UInt",var2) DllCall("oleaut32.dll¥VariantChangeTypeEx","UInt",var2,"UInt",var,"UInt",LOCALE_USER_DEFAULT,"UShort",0,"UShort",0x8) ;値をAnsiに変換 wc2mb_ref(NumGet(var2+8),res) vFree(var2) return res } }else if(rawsize=1){ return NumGet(var+8,0,"UChar") }else if(rawsize=2){ return NumGet(var+8,0,"UShort") }else if(rawsize=4){ return NumGet(var+8) }else{ return fromVariant(var,0) } } ;VARIANTを解放(getに-1以外を指定すると、値を取得して返す) vFree(ByRef var,get=-1){ if(get!=-1){ res =fromVariant(var,get) }else{ res =0 } DllCall("oleaut32.dll¥VariantClear","UInt",var) Free(var) return res } /* ********************************** IDispatch用 ********************************** */ ;オブジェクトを生成する CreateObject(clsid,iid="",CLSCTX=5){;CLSCTX_SERVER global IID_IDispatch if(!IID_IDispatch){ ActiveX() } guid =0 if(RegExMatch(clsid,"^¥{[¥-0-9a-fA-F]{36}¥}$")){ guid =GUID(clsid) }else{ guid =ProgID(clsid) } if(iid=""){ iid2 =IID_IDispatch }else{ iid2 =GUID(iid) } ppRes =0 el =DllCall("ole32.dll¥CoCreateInstance","UInt",guid,"UInt",0,"UInt",CLSCTX,"UInt",iid2,"UIntP",ppRes,"UInt") Free(guid) if(iid2!=IID_IDispatch){ Free(iid2) } ErrorLevel =el return ppRes } ;objが持つnameメンバのDispatchIDを得る GetDispID(ByRef obj,name){ global IID_NULL,LOCALE_USER_DEFAULT wName =mb2wc_ref(name) dispid =0 DllCall(M(obj,5),"UInt",obj,"UInt",IID_NULL,"UIntP",wName,"UInt",1,"UInt",LOCALE_USER_DEFAULT,"UIntP",dispid,"UInt") Free(wName) return dispid } ;引数からDISPPARAMSを生成 CreateParam(ByRef p1, ByRef p2, ByRef p3, ByRef p4, ByRef p5, ByRef p6, ByRef p7, ByRef p8, ByRef p9, ByRef p10){ ;引数を数える(0xFFFFFFFFFFFFFFFFの前までが与えられた引数) num =0 format =A_FormatInteger SetFormat,Integer,D Loop,10{ if(p%A_Index%=0xFFFFFFFFFFFFFFFF){ break } num++ } ;num個のVARIANTARG配列を作成 if(num=0){ pvArgs =0 }else{ pvArgs =Malloc(16*num) ptr =pvArgs+16*(num-1) ;引数をセットしていく Loop,%num%{ toVariant(p%A_Index%,ptr) ptr-=16 } } SetFormat,Integer,%format% ;DISPPARAMS作成 res =Malloc(16) NumPut(pvArgs,res+0) NumPut(num,res+8) return res } ;DISPPARAMSを解放 FreeParam(ByRef params){ num =NumGet(params+8) pvArgs =NumGet(params+0) pvNArgs =NumGet(params+4) ;VARIANTARGの解放処理 ptr =pvArgs Loop,%num%{ vFree(ptr) ptr+=16 } ;VARIANTARG自体の解放 Free(ptr) ;rgdispidNamedArgsの解放 if(pvNArgs!=0){ Free(pvNArgs) } ;本体メモリ解放 Free(params) } Invoke(ByRef pObj,ByRef dispid,mode,ByRef params){ global IID_NULL,LOCALE_USER_DEFAULT pvRes =Malloc(16) DllCall("oleaut32.dll¥VariantInit",UInt,pvRes) DllCall(M(pObj,6),UInt,pObj,UInt,dispid,UInt,IID_NULL,UInt,LOCALE_USER_DEFAULT,UInt,mode,UInt,params,UInt,pvRes,UInt,0,UInt,0,UInt) return pvRes } inv(obj,name,p1=0xFFFFFFFFFFFFFFFF,p2=0xFFFFFFFFFFFFFFFF,p3=0xFFFFFFFFFFFFFFFF,p4=0xFFFFFFFFFFFFFFFF,p5=0xFFFFFFFFFFFFFFFF,p6=0xFFFFFFFFFFFFFFFF,p7=0xFFFFFFFFFFFFFFFF,p8=0xFFFFFFFFFFFFFFFF,p9=0xFFFFFFFFFFFFFFFF,p10=0xFFFFFFFFFFFFFFFF){ if((dispid =GetDispID(obj,name))!=0){ params =CreateParam(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) pvRes =Invoke(obj,dispid,1,params) FreeParam(params) return vFree(pvRes,0) } } gp(obj,name,p1=0xFFFFFFFFFFFFFFFF,p2=0xFFFFFFFFFFFFFFFF,p3=0xFFFFFFFFFFFFFFFF,p4=0xFFFFFFFFFFFFFFFF,p5=0xFFFFFFFFFFFFFFFF,p6=0xFFFFFFFFFFFFFFFF,p7=0xFFFFFFFFFFFFFFFF,p8=0xFFFFFFFFFFFFFFFF,p9=0xFFFFFFFFFFFFFFFF,p10=0xFFFFFFFFFFFFFFFF){ if((dispid =GetDispID(obj,name))!=0){ params =CreateParam(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) pvRes =Invoke(obj,dispid,2,params) FreeParam(params) return vFree(pvRes,0) } } pp(obj,name,p1=0xFFFFFFFFFFFFFFFF,p2=0xFFFFFFFFFFFFFFFF,p3=0xFFFFFFFFFFFFFFFF,p4=0xFFFFFFFFFFFFFFFF,p5=0xFFFFFFFFFFFFFFFF,p6=0xFFFFFFFFFFFFFFFF,p7=0xFFFFFFFFFFFFFFFF,p8=0xFFFFFFFFFFFFFFFF,p9=0xFFFFFFFFFFFFFFFF,p10=0xFFFFFFFFFFFFFFFF){ if((dispid =GetDispID(obj,name))!=0){ params =CreateParam(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) ;rgdispidNamedArgsのセット namedArgs =Malloc(4) NumPut(namedArgs,params+4) NumPut(0xFFFFFFFD,namedArgs+0) NumPut(1,params+12) pvRes =Invoke(obj,dispid,4,params) FreeParam(params) return vFree(pvRes) } } /* ********************************** イベントシンク用コールバック関数 ********************************** */ GuidIsEqual(guid1,guid2){ return DllCall("MSVCRT.dll¥memcmp","UInt",guid1,"UInt",guid2,"UInt",16)=0 } EVENTSINK_QueryInterface(pEv,iid,ppv){ global if(GuidIsEqual(iid,NumGet(pEv+8))||GuidIsEqual(iid,IID_IDispatch)||GuidIsEqual(iid,IID_IUnknown)){ NumPut(pEv,ppv+0) DllCall(M(pEv,1),"UInt",pEv) return 0 } NumPut(0,ppv+0) return 0x80004002 } EVENTSINK_AddRef(pEv){ cRef =NumGet(pEv+4) cRef++ NumPut(cRef,pEv+4) return cRef } EVENTSINK_Release(pEv){ cRef =NumGet(pEv+4) cRef-- NumPut(cRef,pEv+4) if(cRef==0){ EVENTSINK_Destructor(pEv) } return cRef } EVENTSINK_GetTypeInfoCount(pEv,pct){ NumPut(0,pct+0) return 0 } EVENTSINK_GetTypeInfo(pEv,info,lcid,pInfo){ return 0x8002000B;DISP_E_BADINDEX } EVENTSINK_GetIDsOfNames(pEv,riid,szNames,cNames,lcid,pDispID){ return 0x80020006;DISP_E_UNKNOWNNAME } EVENTSINK_Invoke(pEv,dispid,riid,lcid,wFlags,params,pvRes,exinf,argerr){ pTypeInfo =NumGet(pEv+24) ;GetNames hr =DllCall(M(pTypeInfo,7),"UInt",pTypeInfo, "UInt",dispid, "UIntP",bstr, "UInt",1, "UIntP",count) if(hr!=0){ return 0 } wc2mb_ref(bstr,ev) cb =GetOleEventCallback(NumGet(pEv+12),ev) if(cb){ DllCall(cb,"UInt",NumGet(pEv+28), "UInt",params, "UInt",pvRes) } } EVENTSINK_Constructor(){ static vtEventSink if(!vtEventSink){ vtEventSink =Malloc(28) NumPut(RegisterCallback("EVENTSINK_QueryInterface"),vtEventSink+0) NumPut(RegisterCallback("EVENTSINK_AddRef"),vtEventSink+4) NumPut(RegisterCallback("EVENTSINK_Release"),vtEventSink+8) NumPut(RegisterCallback("EVENTSINK_GetTypeInfoCount"),vtEventSink+12) NumPut(RegisterCallback("EVENTSINK_GetTypeInfo"),vtEventSink+16) NumPut(RegisterCallback("EVENTSINK_GetIDsOfNames"),vtEventSink+20) NumPut(RegisterCallback("EVENTSINK_Invoke"),vtEventSink+24) } pEv =Malloc(32) NumPut(vtEventSink,pEv+0) return pEv } EVENTSINK_Destructor(pEv){ Release(NumGet(pEv+28)) Free(pEv) } /* ********************************** コネクト用のインターフェイスIDを検索 ********************************** */ find_iid(ByRef obj,ByRef itf,ByRef iid,ByRef refPTypeInfo=0xFFFFFFFFFFFFFFFF){ global LOCALE_USER_DEFAULT ;GetTypeInfo hr =DllCall(M(disp,4),"UInt",obj, "UInt",0, "UInt",LOCALE_USER_DEFAULT, "UIntP",pTypeInfo) if(hr!=0){ return hr } ;GetContainingTypeLib hr =DllCall(M(pTypeInfo,18),"UInt",pTypeInfo, "UIntP",pTypeLib, "UIntP",index) Release(pTypeInfo) if(hr!=0){ return hr } if(!itf){ ;GetTypeInfoOfGuid hr =DllCall(M(pTypeLib,5),"UInt",pTypeLib, "UIntP",iid, "UIntP",refPTypeInfo) Release(pTypeLib) return hr } count =DllCall(M(pTypeLib,3),"UInt",pTypeLib);GetTypeInfoCount found =0 index =0 Loop,%count%{ hr =DllCall(M(pTypeLib,4),"UInt",pTypeLib, "UInt",index, "UIntP",pTypeInfo);GetTypeInfo if(hr!=0){ break } hr =DllCall(M(pTypeInfo,3),"UInt",pTypeInfo, "UIntP",pTypeAttr);GetTypeAttr if(hr!=0){ Release(pTypeInfo) break } if(NumGet(pTypeAttr+40)==5){;typekind==TKIND_COCLASS cTypes =NumGet(pTypeAttr+48,"UShort");cImplTypes type =0 Loop,%cTypes%{ hr =DllCall(M(pTypeInfo,8),"UInt",pTypeInfo, "UInt",type, "UIntP",RefType);GetRefTypeOfImplType if(hr!=0){ break } hr =DllCall(M(pTypeInfo,14),"UInt",pTypeInfo, "UInt",RefType, "UIntP",pImplTypeInfo);GetRefTypeInfo if(hr!=0){ break } ;GetDocumentation hr =DllCall(M(pImplTypeInfo,12),"UInt",pImplTypeInfo, "Int",-1, "UIntP",bstr, "UInt",0, "UInt",0, "UInt",0) if(hr!=0){ Release(pImplTypeInfo) break } wc2mb_ref(bstr,str) if(str==itf){ ;GetTypeAttr if(DllCall(M(pImplTypeInfo,3),"UInt",pImplTypeInfo, "UIntP",pImplTypeAttr)=0){ found =1 iid =Malloc(16) DllCall("kernel32.dll¥RtlMoveMemory", "UInt",iid, "UInt",pImplTypeAttr, "UInt",16) if(refPTypeInfo!=0xFFFFFFFFFFFFFFFF){ refPTypeInfo =pImplTypeInfo AddRef(pImplTypeInfo) } ;ReleaseTypeAttr DllCall(M(pImplTypeInfo,3),"UInt",pImplTypeInfo, "UInt",pImplTypeAttr) } } Release(pImplTypeInfo) if(found||(hr!=0)){ break } type++ } } hr =DllCall(M(pTypeInfo,3),"UInt",pTypeInfo, "UInt",pTypeAttr);ReleaseTypeAttr Release(pTypeInfo) if(found||(hr!=0)){ break } index++ } Release(pTypeLib) if(!found){ return 0x80004002 }else{ return hr } } find_default_source(ByRef obj,ByRef iid,ByRef refPTypeInfo){ global IID_IProvideClassInfo;,IID_IProvideClassInfo2 /* pProvideClassInfo2 =QueryInterface(obj,IID_IProvideClassInfo2) if(ErrorLevel________==0){ ;GetGUID hr =DllCall(M(pProvideClassInfo2,4),"UInt",pProvideClassInfo2, "UInt",1, "UIntP",iid) Release(pProvideClassInfo2) return find_iid(obj,"",iid,refPTypeInfo) } */ pProvideClassInfo =QueryInterface(obj,IID_IProvideClassInfo) if(ErrorLevel!=0){ return ErrorLevel } ;GetClassInfo hr =DllCall(M(pProvideClassInfo,3),"UInt",pProvideClassInfo, "UIntP",pTypeInfo) Release(pProvideClassInfo) if(hr!=0){ return hr } ;GetTypeAttr hr =DllCall(M(pTypeInfo,3),"UInt",pTypeInfo, "UIntP",pTypeAttr) if(hr!=0){ Release(pTypeInfo) return hr } cTypes =NumGet(pTypeAttr+48,"UShort");cImplTypes type =0 Loop,%cTypes%{ hr =DllCall(M(pTypeInfo,9),"UInt",pTypeInfo, "UInt",type, "UIntP",iFlags);GetImplTypeFlags if(hr!=0){ continue } if((iFlags 0x3)=0x3){;((iFlags IMPLTYPEFLAG_FDEFAULT) (iFlags IMPLTYPEFLAG_FSOURCE)) hr =DllCall(M(pTypeInfo,8),"UInt",pTypeInfo, "UInt",type, "UIntP",RefType);GetRefTypeOfImplType if(hr!=0){ continue } hr =DllCall(M(pTypeInfo,14),"UInt",pTypeInfo, "UInt",RefType, "UIntP",refPTypeInfo);GetRefTypeInfo if(hr!=0){ break } } type++ } DllCall(M(pTypeInfo,3),"UInt",pTypeInfo, "UInt",pTypeAttr);ReleaseTypeAttr Release(pTypeInfo) if(!refPTypeInfo){ if(hr==0){ return 0x8000FFFF }else{ return hr } } if(DllCall(M(refPTypeInfo,3),"UInt",refPTypeInfo, "UIntP",pTypeAttr)=0){;GetTypeAttr iid =Malloc(16) DllCall("kernel32.dll¥RtlMoveMemory", "UInt",iid, "UInt",pTypeAttr, "UInt",16) DllCall(M(refPTypeInfo,3),"UInt",refPTypeInfo, "UInt",pTypeAttr);ReleaseTypeAttr }else{ Release(refPTypeInfo) refPTypeInfo ="" } return hr } EntryOleEventPrefix(ByRef prefix){ global static OleEventCount=0 if(OleEventID_%prefix%){ return OleEventID_%prefix% }else{ OleEventID_%prefix% =OleEventCount OleEventPrefix_%OleEventCount% =prefix return OleEventCount++ } } GetOleEventCallback(id,ByRef evt){ global local prefix,cb prefix =OleEventPrefix_%id% if(prefix){ if(OleEventCallback_%prefix%%evt%){ return OleEventCallback_%prefix%%evt% } cb =RegisterCallback(prefix . evt) if(cb){ OleEventCallback_%prefix%%evt% =cb return cb } } } ConnectObject(obj,prefix,itf=0xFFFFFFFFFFFFFFFF){ global IID_IConnectionPointContainer if(itf==0xFFFFFFFFFFFFFFFF){ hr =find_default_source(obj,iid,pTypeInfo) }else{ hr =find_iid(obj,itf,iid,pTypeInfo) } if(hr!=0){ ErrorLevel =hr return 0 } pContainer =QueryInterface(obj,IID_IConnectionPointContainer) if(ErrorLevel!=0){ Release(pTypeInfo) return 0 } ;FindConnectionPoint hr =DllCall(M(pContainer,4),"UInt",pContainer, "UInt",iid, "UIntP",pConnectionPoint) Release(pContainer) if(hr!=0){ Release(pTypeInfo) return 0 } pIEV =EVENTSINK_Constructor() NumPut(iid,pIEV+8) ;Advise hr =DllCall(M(pConnectionPoint,5),"UInt",pConnectionPoint, "UInt",pIEV, "UIntP",dwCookie) if(hr!=0){ return 0 } AddRef(obj) evid =EntryOleEventPrefix(prefix) NumPut(evid,pIEV+12) NumPut(dwCookie,pIEV+16) NumPut(pConnectionPoint,pIEV+20) NumPut(pTypeInfo,pIEV+24) NumPut(obj,pIEV+28) } evArgc(ByRef para){ return NumGet(para+8) } evArgv(ByRef para,idx){ num =NumGet(para+8) if(idx num){ return fromVariant(NumGet(para+0)+(num-1-idx)*16) } } evReturn(ByRef res,value){ toVariant(value,res) } /* ********************************** ディスパッチオブジェクト作成 ********************************** */ DISPATCH_QueryInterface(ptr,iid,ppv){ global if(GuidIsEqual(iid,IID_IDispatch)||GuidIsEqual(iid,IID_IUnknown)){ NumPut(ptr,ppv+0) DllCall(M(ptr,1),"UInt",ptr) return 0 }else{ NumPut(0,ppv+0) return 0x80004002 } } DISPATCH_AddRef(ptr){ cRef =NumGet(ptr+4) cRef++ NumPut(cRef,ptr+4) return cRef } DISPATCH_Release(ptr){ cRef =NumGet(ptr+4) cRef-- NumPut(cRef,ptr+4) if(cRef==0){ Free(ptr) } return cRef } DISPATCH_GetTypeInfoCount(ptr,pct){ NumPut(0,pct+0) return 0 } DISPATCH_GetTypeInfo(ptr,info,lcid,pInfo){ return 0x8002000B;DISP_E_BADINDEX } DISPATCH_GetIDsOfNames(ptr,riid,pszNames,cNames,lcid,pDispID){ wc2mb_ref(NumGet(pszNames+0),name) hr =GetOleMethodCallback(NumGet(ptr+12),name,cb) NumPut(cb,pDispID+0) return hr } DISPATCH_Invoke(ptr,dispid,riid,lcid,wFlags,params,pvRes,exinf,argerr){ DllCall(dispid,"UInt",ptr, "UInt",params, "UInt",pvRes, "UInt",wFlags) return 0 } EntryOleMethodsPrefix(ByRef prefix,ByRef id){ global static OleMethodsCount=0 if(OleMethodsID_%prefix%){ id =OleMethodsID_%prefix% }else{ OleMethodsID_%prefix% =OleMethodsCount OleMethodsPrefix_%OleMethodsCount% =prefix id =OleMethodsCount++ } } GetOleMethodCallback(id,ByRef name,ByRef cb){ global local prefix cb =0 prefix =OleMethodsPrefix_%id% if(prefix){ if(OleMethodCallback_%prefix%%name%){ cb =OleMethodCallback_%prefix%%name% return 0 }else{ cb =RegisterCallback(prefix . name) if(cb){ OleMethodCallback_%prefix%%name% =cb return 0 }else{ return 0x80020006 } } } } CreateDispatchObject(prefix,exsize=0){ global IID_IDispatch static vtDispatch if(!vtDispatch){ vtDispatch =Malloc(28) NumPut(RegisterCallback("DISPATCH_QueryInterface"),vtDispatch+0) NumPut(RegisterCallback("DISPATCH_AddRef"),vtDispatch+4) NumPut(RegisterCallback("DISPATCH_Release"),vtDispatch+8) NumPut(RegisterCallback("DISPATCH_GetTypeInfoCount"),vtDispatch+12) NumPut(RegisterCallback("DISPATCH_GetTypeInfo"),vtDispatch+16) NumPut(RegisterCallback("DISPATCH_GetIDsOfNames"),vtDispatch+20) NumPut(RegisterCallback("DISPATCH_Invoke"),vtDispatch+24) } EntryOleMethodsPrefix(prefix,id) ptr =Malloc(12+exsize) NumPut(vtDispatch,ptr+0) NumPut(IID_IDispatch,ptr+8) NumPut(id,ptr+12) return ptr }
https://w.atwiki.jp/wiki7_ahr/pages/22.html
#blognavi ヒープ領域の一貫性をチェックする他の方法としてmcheck()関数の使用があります。 typedef void (*mcheckCallback)(enum mcheck_status status); void mcheck(mcheckCallback cb); mcheck()がコールされると、malloc()は獲得したたメモリ領域の前後に予め定められた バイトシーケンスを配置して領域の境界の前後が不当に上書きされるかどうかの状態変 化を監視出来る様にします。free()はこれ等のシグニチャを捜し、破壊されている事を 検知すると、free()はcbパラメータで指定された関数をコールします。もしcbがNULLで あれば、その代わりにプログラムからexitします。mcheck()をリンクしたプログラムは free()のタイミングでgdbを通じてどのメモリ領域が壊れたかを示す事が出来ます。し かし、memcheck()ではメモリ破壊の発生した場所をピンポイントで特定する事は出来ま せん。この問題を解決するにはプログラムフローを理解しているプログラマの助けが 必要です。mcheck()のリンクと実行例を以下に示します。 gcc -ggdb -o broken broken.c -lmcheck ./broken プログラム実行結果表示 memory clobbered past end of allocated block mcheck()だけでは余り頻繁にエラー表示やexitをしないので、エラー箇所をピンポイント で突き止める事は出来ません。これを実現するにはmcheck()をリンクしたプログラムを gdb上で実行して問題を認知してabort()する必要があります。そのためにはプログラムで 最初にmalloc()を呼出す前に、gdbからcall mcheck()もしくはcall mcheck(1)を実行する だけです。(特記事項:gdbからのmcheck()呼出しを行なうのに、実行プログラムがmcheck ライブラリとリンクしている必要はありません!) 以下に実行例を示します。 gdb broken . . . (gdb) break main Breakpoint 1 at 0x80483f4 file broken.c, line 14. (gdb) command 1 Type commands for when breakpoint 1 is hit, one per line. End with a line saying just "end". call mcheck( abort) continue end (gdb) run Starting program /usr/src/myprogram/broken Breakpoint 1, main() at broken.c 14 47 return broken(); $1 = 0 1 12345 Program received signal SIGABORT, Aborted. 0x00e12c32 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2 (gdb) where #0 0x00e12c32 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2 #1 0x0072c969 in rase () from /lib/tls/libc.so.6 #2 0x0072e322 in abort () from /lib/tls/libc.so.6 #3 0x007792c4 in freehook () from /lib/tls/libc.so.6 #4 0x00774fa5 in free () from /lib/tls/libc.so.6 #5 0x0804842b in broken () at broken.c 17 #6 0x08048520 in main () at broken.c 47 mcheck()はmalloc()されたメモリ領域関連のオーバーフローもしくはアンダーランのみ を検知します。ローカルもしくはグローバル変数のエラーは検知しません。 参考文献 (リスト部分を引用) Linux Application Development -second edition Author Michael K. Johnson, Erik W. Troan (c)2005 Pearson Education, Inc. ISBN 0-321-21914-7 カテゴリ [メモリ管理] - trackback- 2006年03月15日 02 00 47 #blognavi